﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
using System.Windows.Threading;
using GameLogic.Controls;

namespace GameLogic.Controls
{
    [TemplatePart(Name = C_ScoresTextName, Type = typeof(TextBlock))]
    public class ScoreControl : Control
    {
        const string C_ScoresTextName = "_scoresText";
        TextBlock scoresText;
        int currentValue;

        public event EventHandler<ScoresChangedEventArgs> ScoresChanged;
        public event EventHandler ScoresVictory;
        public event EventHandler ScoresDefeat;

        #region Dependency Properties
        [Category("Scores")]
        public int StartValue
        {
            get { return (int)GetValue(StartValueProperty); }
            set { SetValue(StartValueProperty, value); }
        }
        public static readonly DependencyProperty StartValueProperty =
           DependencyProperty.Register(
           "StartValue", 
           typeof(int), 
           typeof(ScoreControl), 
           new PropertyMetadata(0, null));

        [Category("Scores")]
        public int DefeatValue
        {
            get { return (int)GetValue(DefeatValueProperty); }
            set { SetValue(DefeatValueProperty, value); }
        }
        public static readonly DependencyProperty DefeatValueProperty =
            DependencyProperty.Register(
            "DefeatValue", 
            typeof(int), 
            typeof(ScoreControl), 
            new PropertyMetadata(0, null));

        [Category("Scores")]
        public int VictoryValue
        {
            get { return (int)GetValue(VictoryValueProperty); }
            set { SetValue(VictoryValueProperty, value); }
        }
        public static readonly DependencyProperty VictoryValueProperty =
            DependencyProperty.Register(
            "VictoryValue", 
            typeof(int), 
            typeof(ScoreControl), 
            new PropertyMetadata(100, null));

        [Category("Scores")]
        public bool IsVictoryCondition
        {
            get { return (bool)GetValue(IsVictoryConditionProperty); }
            set { SetValue(IsVictoryConditionProperty, value); }
        }
        public static readonly DependencyProperty IsVictoryConditionProperty =
            DependencyProperty.Register(
                "IsVictoryCondition", 
                typeof(bool), 
                typeof(ScoreControl), 
                new PropertyMetadata(false, null));

        [Category("Scores")]
        public bool IsDefeatCondition
        {
            get { return (bool)GetValue(IsDefeatConditionProperty); }
            set { SetValue(IsDefeatConditionProperty, value); }
        }
        public static readonly DependencyProperty IsDefeatConditionProperty =
            DependencyProperty.Register(
                "IsDefeatCondition", 
                typeof(bool), 
                typeof(ScoreControl), 
                new PropertyMetadata(false, null));

        #endregion

        public int CurrentValue
        {
            get { return currentValue; }
        }

        // Constructor
        public ScoreControl()
        {
            this.DefaultStyleKey = typeof(ScoreControl);
            currentValue = this.StartValue;
        }  
        
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            scoresText = GetTemplateChild(C_ScoresTextName) as TextBlock;
            scoresText.Text = this.CurrentValue.ToString();
        }

        public void Initialize()
        {
            currentValue = this.StartValue;
            this.UpdateDisplay();
        }

        public void Add(int value)
        {
            currentValue += value;
            this.UpdateDisplay();
            this.OnScoresChanged(value);
        }

        private void OnScoresChanged(int value)
        {
            if (this.ScoresChanged != null)
            {
                ScoresChangedEventArgs args = new ScoresChangedEventArgs();
                args.Value = value;
                this.ScoresChanged(this, args);
            }

            if (this.IsDefeatCondition)
            {
                if ((this.CurrentValue <= this.DefeatValue && this.StartValue > this.DefeatValue) ||
                    (this.CurrentValue >= this.DefeatValue && this.StartValue < this.DefeatValue))
                {
                    this.OnScoresDefeat();
                }
            }
            else if (this.IsVictoryCondition)
            {
                if ((this.CurrentValue >= this.VictoryValue && this.StartValue < this.VictoryValue) ||
                    (this.CurrentValue <= this.VictoryValue && this.StartValue > this.VictoryValue))
                {
                    this.OnScoresVictory();
                }
            }
        }

        private void OnScoresVictory()
        {
            if (this.ScoresVictory != null)
            {
                ScoresVictory(this, EventArgs.Empty);
            }
        }

        private void OnScoresDefeat()
        {
            if (this.ScoresDefeat != null)
            {
                ScoresDefeat(this, EventArgs.Empty);
            }
        }

        private void UpdateDisplay()
        {
            // Only update if visible
            if (scoresText != null)
            {
                scoresText.Text = currentValue.ToString();
                UpdateLayout();
            }
        }
    }
}
